package com.terabits.smartriver.service.impl;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONArray;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import com.terabits.smartriver.constants.ModelEnum;
import com.terabits.smartriver.mapper.*;
import com.terabits.smartriver.meta.dto.ExcelData;
import com.terabits.smartriver.meta.dto.MongoData;
import com.terabits.smartriver.meta.po.*;
import com.terabits.smartriver.service.CalculationService;
import com.terabits.smartriver.service.DataViewService;
import com.terabits.smartriver.util.*;
import org.apache.ibatis.annotations.Delete;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.terabits.smartriver.util.CalculationUtils.isNumeric;
import static com.terabits.smartriver.util.DateUtils.*;

/**
 * Created by Yin on 2019/3/22
 */
@Service
@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class DataViewServiceImpl extends BaseService implements DataViewService {
    @Resource
    private EnterpriseMapper enterpriseMapper;
    @Resource
    private ProjectMapper projectMapper;
    @Resource
    private AlarmMapper alarmMapper;
    @Resource
    private CalculationService calculationService;
    @Resource
    private ModelMapper modelMapper;
    @Resource
    private DeviceMapper deviceMapper;
    @Resource
    private BoxMapper boxMapper;
    @Resource
    private MongoManager mongoManager;
    @Resource
    private ConcentrationMapper concentrationMapper;

    @Override
    public List getMapEnterprise(PageData pageData) {
        String roleProjectNum = String.valueOf(pageData.get("roleProjectNum"));
        if (!StringUtils.isEmpty(roleProjectNum) && !"null".equals(roleProjectNum)) {
            Project project = new Project();
            project.setProjectNum(roleProjectNum);
            List<Project> select = projectMapper.select(project);
            Integer enterpriseId = select.get(0).getEnterpriseId();
            pageData.put("enterpriseId", enterpriseId);
        }
        //todo color为null
        List<PageData> result = alarmMapper.selectMapEnterprise(pageData);

        for (PageData one : result) {
            if (StringUtils.isEmpty(one.getString("color"))) {
                one.put("color", "0");
            }
        }
        return result;
    }

    @Override
    public List getMapProject(PageData pageData) {
        List result = alarmMapper.selectMapProjectDevices(pageData);
        return result;
    }

    @Override
    public List getRealstatus(PageData pageData) {
        List<Map> result = new ArrayList<>();
        List<Project> projects = null;
        Object enterprisename = pageData.get("enterprisename");
        Object roleProjectNum = pageData.get("roleProjectNum");
        Enterprise enterprise = new Enterprise();
        Project project1 = new Project();
        if (!"null".equals(roleProjectNum)) {
            if (!ObjectUtils.isEmpty(enterprisename)) {
                enterprise.setName(String.valueOf(enterprisename));
                List<Enterprise> enterprises = enterpriseMapper.select(enterprise);
                Enterprise enterprise1 = enterprises.get(0);
                Integer id = enterprise1.getId();
                project1.setEnterpriseId(id);
                projects = projectMapper.select(project1);
            } else {
                project1.setProjectNum(String.valueOf(roleProjectNum));
                projects = projectMapper.select(project1);
            }
        } else {
            if (!ObjectUtils.isEmpty(enterprisename)) {
                enterprise.setName(String.valueOf(enterprisename));
                List<Enterprise> enterprises = enterpriseMapper.select(enterprise);
                Enterprise enterprise1 = enterprises.get(0);
                Integer id = enterprise1.getId();
                project1.setEnterpriseId(id);
                projects = projectMapper.select(project1);
            } else {
                projects = projectMapper.selectAll();
            }
        }

        projects.stream().forEach(project -> {
            Map map = new HashMap();
            String projectNum = project.getProjectNum();
            String projectName = project.getName();
            Box box = new Box();
            box.setProjectNum(projectNum);
            List<Box> boxs = boxMapper.select(box);
            enterprise.setId(project.getEnterpriseId());
            List<Enterprise> enterprises = enterpriseMapper.select(enterprise);
            String name = enterprises.get(0).getName();
            if (boxs.size() == 0) {
                map.put("enterpriseName", name);
                map.put("project", projectName);
                map.put("online", 0);
                map.put("offline", 0);
                map.put("abnormal", 0);
            } else {
                List<Box> onlineBox = boxs.stream().filter(box1 -> box1.getStatus() == 0).collect(Collectors.toList());
                map.put("enterpriseName", name);
                map.put("project", projectName);
                map.put("online", onlineBox.size());
                List<Box> offline = boxs.stream().filter(box1 -> box1.getStatus() == 3).collect(Collectors.toList());
                map.put("offline", offline.size());
                List<Box> abnormal = boxs.stream().filter(box1 -> box1.getStatus() == 2).collect(Collectors.toList());
                map.put("abnormal", abnormal.size());
            }
            result.add(map);
        });
        return result;
    }

    @Override
    public List getRealdata(PageData pageData) {
        return enterpriseMapper.selectRealdata(pageData);
    }

    @Override
    public PageData getData(PageData pageData) {
        PageData result = new PageData();
        String currentDate = getDate(null, null, 0);
        String currentYear = DateToString(new Date(), "yyyy");
        String projectNum = null;
        Project project = null;
        projectNum = pageData.getString("ProjectNum");
        if (!"null".equals(projectNum)) {
            Project project1 = new Project();
            project1.setProjectNum(pageData.getString("ProjectNum"));
            List<Project> select = projectMapper.select(project1);
            project = select.get(0);
        } else {
            project = projectMapper.selectByPrimaryKey(Integer.parseInt(pageData.getString("projectId")));
            projectNum = project.getProjectNum();
        }
        if (calculationService.getTreatment(projectNum) == 0) {
            result.put("暂无数据", null);
            return result;
        }


        PageData pd = new PageData();
        pd.put("projectNum", project.getProjectNum());


        result.put("project", project.getName());
        //今日处理水量
//        String water_today = calculationService.treatmentOfWater(getTime(-1), getTime(0), projectNum);
//        if ("未对项目配置设备".equals(water_today) || "暂无数据".equals(water_today)) {
//            PageData waterToday = calculationService.getTreatment(getDate(null, null, null) + " 00:00:00", getTime(0), projectNum);
//            if (!StringUtils.isEmpty(waterToday)) {
//                result.put("water_today", String.format("%.2f", Convert.toDouble(waterToday.get("water"))));
//            }
        result.put("water_today", "暂无数据");
//        } else {
//            result.put("water_today", String.format("%.2f", Convert.toDouble(water_today)));
//        }
        //昨日处理水量
        PageData waterYesterday = calculationService.getTreatment(getDate(null, null, -1), getDate(null, null, -1), projectNum);
        if (StringUtils.isEmpty(waterYesterday)) {
            result.put("water_yesterday", "暂无数据");
        } else {
            result.put("water_yesterday", String.format("%.2f", Convert.toDouble(waterYesterday.get("water"))));

        }
        //30日处理水量
        PageData water30day = calculationService.getTreatment(getDate(null, null, -30), currentDate, projectNum);
        if (StringUtils.isEmpty(water30day)) {
            result.put("water_30day", "暂无数据");
        } else {
            result.put("water_30day", String.format("%.2f", Convert.toDouble(water30day.get("water"))));
        }

        //今年鱼季处理水量
        PageData waterFishseason = calculationService.getTreatment(currentYear + "-05-01", currentYear + "-10-31", projectNum);
        if (StringUtils.isEmpty(waterFishseason)) {
            result.put("water_fishseason", "暂无数据");
        } else {
            result.put("water_fishseason", String.format("%.2f", Convert.toDouble(waterFishseason.get("water"))));
        }

        //今年累计处理水量
        PageData waterYear = calculationService.getTreatment(currentYear + "-01-01", currentDate, projectNum);
        if (StringUtils.isEmpty(waterYear)) {
            result.put("water_year", "暂无数据");
        } else {
            result.put("water_year", String.format("%.2f", Convert.toDouble(waterYear.get("water"))));
        }
        //月每亩处理水量
        PageData water = calculationService.getTreatment(getDate(null, 1, null), getDate(null, null, -1), projectNum);
        if (water != null && water.get("water") != null && project.getScale() != null) {
            Double scale = project.getScale();
            Double shuiLiangMonth = Convert.toDouble(water.get("water")) / scale;
            String substring = null;
            substring = String.format("%.2f", shuiLiangMonth);
            result.put("water_monthmu", substring);
        } else {
            result.put("water_monthmu", "暂无数据");
        }
        //月设备异常次数
        result.put("exception_device", alarmMapper.selectCountByProjectOther(projectNum));
        //月水质异常次数
        result.put("exception_water", alarmMapper.selectCountByProjectWater(projectNum));

        String cod = "暂无数据";
        String nh3n = "暂无数据";
        String p = "暂无数据";
        String ss = "暂无数据";
        PageData volume = calculationService.getTreatment(getDate(0, 1, null), currentDate, projectNum);

        if (volume != null) {
            cod = String.format("%.2f", Convert.toDouble(volume.get("cod")));
            nh3n = String.format("%.2f", Convert.toDouble(String.valueOf(volume.get("nh3n"))));
            p = String.format("%.2f", Convert.toDouble(String.valueOf(volume.get("p"))));
            ss = String.format("%.2f", Convert.toDouble(String.valueOf(volume.get("ss"))));
        }

        //COD浓度（月处理）
        result.put("COD", cod);
        //氨氮（月处理）
        result.put("NH4N", nh3n);
        //总磷（月处理）
        result.put("P", p);
        //悬浮物（月处理）
        result.put("SS", ss);


        result.putAll(getArr6Month(projectNum));
        result.putAll(getArr7Day(projectNum));

        return result;
    }


    @Override
    public List getWaterQuality(PageData pageData) {
        List<PageData> results = alarmMapper.selectWaterQuality(pageData);
        return results;
    }

    @Override
    public List getSampling(PageData pageData) {
        List<PageData> results = alarmMapper.selectWaterSampling(pageData);
        return results;
    }

    @Override
    public List<PageData> getConcentration(PageData pageData) {
        return concentrationMapper.selectConcentration(pageData);
    }

    @Override
    public int addConcentration(List<Concentration> concentration) {
        Integer integer = 1;
        concentration.forEach(concentrationInfo -> {
            if (StringUtils.isEmpty(concentrationInfo)) {
                return;
            }
            if (StringUtils.isEmpty(concentrationInfo.getInConcentration()) || StringUtils.isEmpty(concentrationInfo.getOutConcentration())) {
                return;
            }
            Concentration delete = new Concentration();
            delete.setProjectNum(concentrationInfo.getProjectNum());
            delete.setBoxNum(concentrationInfo.getBoxNum());
            delete.setType(concentrationInfo.getType());
            //由于这里不好往date里塞值，只有随便借助一个参数来赋值进行删除，写法严重有问题
            delete.setInConcentration(concentrationInfo.getDate());
            concentrationMapper.deleteConcentration(delete);

            concentrationInfo.setDate(concentrationInfo.getDate());
            concentrationMapper.insertSelective(concentrationInfo);
        });

        return integer;
    }

    @Override
    public int updateConcentration(Integer id, String inConcentration, String outConcentration) {
        Concentration concentration = new Concentration();
        concentration.setId(id);
        concentration.setInConcentration(inConcentration);
        concentration.setOutConcentration(outConcentration);
        int i = concentrationMapper.updateByPrimaryKeySelective(concentration);
        return i;
    }

    @Override
    public int deleteConcentration(Integer id) {
        Concentration concentration = new Concentration();
        concentration.setId(id);
        int delete = concentrationMapper.delete(concentration);
        return delete;
    }

    @Override
    public boolean excelExport(List<String> concentrationIds, HttpServletResponse response) {
        String fileName = ExportType.getExportFilename(1);
        String[] head = {"序号", "所属项目编号", "所属项目", "所属盒子", "浓度种类", "进浓度", "出浓度", "创建时间"};
        List<String[]> list = new ArrayList<String[]>();
        int i = 1;
        // 第五步，写入实体数据 实际应用中这些数据从数据库得到
        for (String concentrationId : concentrationIds) {
            String[] arrs = new String[8];
            Concentration concentration = new Concentration();
            concentration.setId(Integer.valueOf(concentrationId));
            List<Concentration> concentrations = concentrationMapper.select(concentration);
            if (concentrations.size() == 0) {
                return false;
            }
            Concentration concentration1 = concentrations.get(0);

            arrs[0] = String.valueOf(i);
            arrs[1] = concentration1.getProjectNum();
            Project project = new Project();
            project.setProjectNum(concentration1.getProjectNum());
            List<Project> select = projectMapper.select(project);
            if (concentrations.size() == 0) {
                return false;
            }
            Project project1 = select.get(0);
            arrs[2] = project1.getName();
            arrs[3] = concentration1.getBoxNum();
            String exportFilename = ConcentrationType.getExportFilename(concentration1.getType());
            arrs[4] = exportFilename;
            arrs[5] = concentration1.getInConcentration();

            arrs[6] = concentration1.getOutConcentration();
            arrs[7] = concentration1.getDate();
            list.add(arrs);
            i++;
        }
        ExcelData data = new ExcelData();
        data.setFileName(fileName);
        data.setData(list);
        data.setHead(head);
        try {
            ExcelUtil.exportExcel(response, data);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    //获得近六个月数据图表
    private Map getArr6Month(String projectNum) {
        Map result = new HashMap();

        List<PageData> cod = new ArrayList<>();
        List<PageData> nh3n = new ArrayList<>();
        List<PageData> p = new ArrayList<>();
        List<PageData> ss = new ArrayList<>();

        for (int i = 1; i < 7; i++) {
            String begin = getDate(i - 6, 1, null);
            String end = getDate(i - 5, 1, -1);


            PageData volume = calculationService.getTreatment(begin, end, projectNum);
            if (volume == null) {
                volume = new PageData();
            }
            String date = begin.substring(0, 7);

            PageData one1 = new PageData();
            one1.put("date", date);
            one1.put("value", volume.get("cod"));
            cod.add(one1);

            PageData one2 = new PageData();
            one2.put("date", date);
            one2.put("value", volume.get("nh3n"));
            nh3n.add(one2);

            PageData one3 = new PageData();
            one3.put("date", date);
            one3.put("value", volume.get("p"));
            p.add(one3);

            PageData one4 = new PageData();
            one4.put("date", date);
            one4.put("value", volume.get("ss"));
            ss.add(one4);
        }

        result.put("codM", cod);
        result.put("nh3nM", nh3n);
        result.put("pM", p);
        result.put("ssM", ss);
        return result;
    }

    //获得近7天数据图表
    private Map getArr7Day(String projectNum) {
        Map result = new HashMap();

        List<PageData> cod = new ArrayList<>();
        List<PageData> nh3n = new ArrayList<>();
        List<PageData> p = new ArrayList<>();
        List<PageData> ss = new ArrayList<>();

        for (int i = 0; i < 7; i++) {
            String date = getDate(null, null, i - 7);
            PageData volume = calculationService.getTreatment(date, date, projectNum);
            if (volume == null) {
                volume = new PageData();
            }

            date = date.substring(5);
            PageData one1 = new PageData();
            one1.put("date", date);
            one1.put("value", volume.get("cod"));
            cod.add(one1);

            PageData one2 = new PageData();
            one2.put("date", date);
            one2.put("value", volume.get("nh3n"));
            nh3n.add(one2);

            PageData one3 = new PageData();
            one3.put("date", date);
            one3.put("value", volume.get("p"));
            p.add(one3);

            PageData one4 = new PageData();
            one4.put("date", date);
            one4.put("value", volume.get("ss"));
            ss.add(one4);

        }

        result.put("codD", cod);
        result.put("nh3nD", nh3n);
        result.put("pD", p);
        result.put("ssD", ss);
        return result;
    }
}